/*
 * File:    Driver.java
 * Created: 11-Jan-2008
 *
 * by Kenji Hollis <kenji@bitgatesoftware.com>
 * Released under the Creative Commons License version 2.5
 */

package com.bitgate.util.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * This class is an enumeration class, which can be used for quick access to a database.  It automatically instantiates the
 * class name for the driver you specify when retrieving a new connection.
 * <p></p>
 * Available drivers are: SQLITE, MYSQL, POSTGRESQL, POSTGRES, HYPERSONIC, HSQL, and H2.
 * 
 * @author kenji
 * @since 0.2.0
 */
public enum Driver
{
	/** This is a SQLiteJDBC driver connection. */
	SQLITE		("org.sqlite.JDBC",			"jdbc:sqlite:"),
	
	/** This is a MySQL JDBC driver connection - this is <b>not to be used in a pooling environment</b>. */
	MYSQL		("com.mysql.jdbc.Driver",	"jdbc:mysql:"),
	
	/** This is a PostgreSQL JDBC driver connection. */
	POSTGRESQL	("org.postgresql.Driver",	"jdbc:postgresql:"),
	
	/** This is an alias to the PostgreSQL JDBC driver connection. */
	POSTGRES	("org.postgresql.Driver",	"jdbc:postgresql:"),
	
	/** This is a Hypersonic SQL JDBC driver connection. */
	HYPERSONIC	("org.hsqldb.jdbcDriver",	"jdbc:hsqldb:"),
	
	/** This is an alias to the Hypersonic SQL JDBC driver connection. */
	HSQL		("org.hsqldb.jdbcDriver",	"jdbc:hsqldb:"),
	
	/** This is an H2 SQL JDBC driver connection. */
	H2			("org.h2.Driver",			"jdbc:h2:");
	
	private final String databaseClass;
	private final String jdbcRootString;
	
	private Driver(String databaseClass, String jdbcRootString) {
		this.databaseClass = databaseClass;
		this.jdbcRootString = jdbcRootString;
	}
	
	/**
	 * Returns a class instance.
	 * 
	 * @return <code>Class&lt;?&gt;</code> object.
	 * @throws ClassNotFoundException if the JDBC class could not be located.
	 */
	public Class<?> getInstance() throws ClassNotFoundException {
		return Class.forName(databaseClass);
	}
	
	/**
	 * Returns the classname associated with the driver you specified.
	 * 
	 * @return <code>String</code> containing the driver name.
	 */
	public String getClassName() {
		return databaseClass;
	}
	
	/**
	 * Contains the start of the JDBC connect string for the driver you specified.
	 * 
	 * @return <code>String</code> containing the JDBC connection string "start of string" message for a new {@link Connection}
	 * object.
	 */
	public String getConnectionRootString() {
		return jdbcRootString;
	}
	
	/**
	 * Returns a new {@link Connection} to the SQL server based on the string given (specifies the database, parameters, etc.)
	 * 
	 * @param connectionString <code>String</code> containing the connection parameters.
	 * @return {@link Connection} containing a new connection to the SQL server.
	 * @throws SQLException on any errors.
	 */
	public Connection get(String connectionString) throws DBException {
		try {
			getInstance();
			return DriverManager.getConnection(jdbcRootString + connectionString);
		} catch(SQLException e) {
			throw new DBException(jdbcRootString + connectionString + ": " + e.getMessage(), e);
		} catch(ClassNotFoundException e) {
			throw new DBException(jdbcRootString + connectionString + ": Class not found, check your classpath.");
		}
	}
	
	/**
	 * Returns a new {@link Connection} to the SQL server based on the user/pass parameters given as well.
	 * 
	 * @param connectionString <code>String</code> containing the connection parameters.
	 * @param user <code>String</code> containing the username to connect with.
	 * @param pass <code>String</code> containing the password to connect with.
	 * @return <code>Connection</code> containing a new connection to the SQL server.
	 * @throws SQLException on any errors.
	 */
	public Connection get(String connectionString, String user, String pass) throws DBException {
		try {
			getInstance();
			return DriverManager.getConnection(jdbcRootString + connectionString, user, pass);
		} catch(SQLException e) {
			throw new DBException(jdbcRootString + connectionString + " (with user/pass): " + e.getMessage(), e);
		} catch(ClassNotFoundException e) {
			throw new DBException(jdbcRootString + connectionString + ": Class not found, check your classpath.");
		}
	}
}